package com.example.testcamera2;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.Face;
import android.hardware.camera2.params.RggbChannelVector;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.AudioRouting;
import android.media.FaceDetector;
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.MediaScannerConnection;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.Permission;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @author CYGL
 * @date 2021/5/30
 * GitEE: gitee.com/cygl
 * Dsecription:
 */
public class MainActivity extends AppCompatActivity {
    private static final SparseIntArray ORIENTATION = new SparseIntArray();

    private void front() {
        //前置时，照片竖直显示
        ORIENTATION.append(Surface.ROTATION_0, 270);
        ORIENTATION.append(Surface.ROTATION_90, 0);
        ORIENTATION.append(Surface.ROTATION_180, 90);
        ORIENTATION.append(Surface.ROTATION_270, 180);
    }

    static {
        ORIENTATION.append(Surface.ROTATION_0, 90);
        ORIENTATION.append(Surface.ROTATION_90, 0);
        ORIENTATION.append(Surface.ROTATION_180, 270);
        ORIENTATION.append(Surface.ROTATION_270, 180);
    }

    private String mCameraId;
    private Size mPreviewSize;
    private Size mCaptureSize;
    private Size mVideoSize;
    private HandlerThread mCameraThread;
    private Handler mCameraHandler;
    private CameraDevice mCameraDevice;
    private TextureView mTextureView;
    private ImageReader mImageReader;
    private CaptureRequest.Builder mCaptureRequestBuilder;
    private CaptureRequest.Builder mCaptureVideoBuilder;
    private CaptureRequest.Builder mCaptureBuilder;
    private CaptureRequest mCaptureRequest;
    private CameraCaptureSession mCameraCaptureSession;
    private CameraCaptureSession mCameraVideoSession;
    private MediaRecorder mMediaRecorder;
    private List<Surface> surfaces = new ArrayList<>();
    private ImageView mImageView;
    private ImageView mImageView2;
    private Button layBtn;
    private Button stopBtn;
    private Button startBtn;
    private TextView txt_3s;
    private TextView txt_5s;
    private TextView txt_10s;
    private Bitmap bitmap;
    private int mLayTime;
    private int lih = 0;
    private int model = 1;
    private CountDownTimer count;
    private MediaPlayer mMediaPlayer;
    private Integer mFaceDetectMode;
    private boolean mFaceDetectSupported;
    private TextView faceText;
    private TextView slowText;
    private Handler faceHandler;
    private Chronometer mChronometer;
    private int stateTime = 1;
    private Button startSlow;
    private Button stopSlow;
    private int stateSlow = 1;
    private TextView awb_txt;
    private ImageView awb_img_room;
    private ImageView awb_img_sun;
    private ImageView awb_img_cloud;
    private int stateAwb = 1;
    private Rect mCameraRect;
    private Size mCameraPixelSize;
    private FaceView faceView;
    private Paint mPaint;
    private int maxFaceCount;
    private String msg = "";
    private int stateCapture = 1;
    private Button captureBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.RECORD_AUDIO,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION}, 1);

        //全屏无状态栏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        //获取权限
        //initPermission();
        //获取地理位置
        getLocation();
        //初始化Fragment
        Fragment takePhotoFrag = (Fragment) getSupportFragmentManager().findFragmentById(R.id.take_photo);
        Fragment takeVideoFrag = (Fragment) getSupportFragmentManager().findFragmentById(R.id.take_video);
        Fragment takeFull = (Fragment) getSupportFragmentManager().findFragmentById(R.id.take_full);
        getSupportFragmentManager().beginTransaction().show(takePhotoFrag).commit();
        getSupportFragmentManager().beginTransaction().hide(takeVideoFrag).commit();
        getSupportFragmentManager().beginTransaction().hide(takeFull).commit();
        startBtn = takeVideoFrag.getView().findViewById(R.id.video_start);
        stopBtn = takeVideoFrag.getView().findViewById(R.id.video_stop);
        stopBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopRecordingVideo();
                startBtn.setVisibility(View.VISIBLE);
                stopBtn.setVisibility(View.GONE);
            }
        });
        findViewById(R.id.choose).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                chooseCamera();
            }
        });
        findViewById(R.id.txt_video).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("TAG", "onClick: ========", null);
                getSupportFragmentManager().beginTransaction().hide(takePhotoFrag).commit();
                getSupportFragmentManager().beginTransaction().hide(takeFull).commit();
                getSupportFragmentManager().beginTransaction().show(takeVideoFrag).commit();
            }
        });
        findViewById(R.id.txt_picture).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("TAG", "onClick: ========", null);
                getSupportFragmentManager().beginTransaction().hide(takeVideoFrag).commit();
                getSupportFragmentManager().beginTransaction().hide(takeFull).commit();
                getSupportFragmentManager().beginTransaction().show(takePhotoFrag).commit();
            }
        });
        findViewById(R.id.txt_full).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("TAG", "onClick: ========", null);
                getSupportFragmentManager().beginTransaction().show(takePhotoFrag).commit();
                getSupportFragmentManager().beginTransaction().hide(takeVideoFrag).commit();
                getSupportFragmentManager().beginTransaction().show(takeFull).commit();

            }
        });
        //切换摄像头
        faceText = findViewById(R.id.face);
        //绑定TextureView
        mTextureView = (TextureView) findViewById(R.id.textureView);
        //ImageView
        mImageView = (ImageView) takePhotoFrag.getView().findViewById(R.id.iv);
        mImageView2 = (ImageView) takeVideoFrag.getView().findViewById(R.id.iv2);
        mImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivity(i);
            }

        });
        //延时拍照
        layBtn = (Button) takeFull.getView().findViewById(R.id.lay_btn);
        layBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (model) {
                    case 1:
                        count = new CountDownTimer(mLayTime, 1000) {
                            @Override
                            public void onTick(long millisUntilFinished) {
                                layBtn.setText("" + millisUntilFinished / 1000);
                                model = 2;
                            }

                            @Override
                            public void onFinish() {
                                layBtn.setText("");
                                takePicture(v);
                                model = 1;
                            }
                        }.start();
                        break;
                    case 2:
                        count.cancel();
                        takePicture(v);
                        layBtn.setText("");
                        model = 1;
                        break;
                }
            }
        });
        txt_3s = (TextView) takeFull.getView().findViewById(R.id.txt_3s);
        txt_3s.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                layBtn.setText("3");
                mLayTime = 3 * 1000;
            }
        });
        txt_5s = (TextView) takeFull.getView().findViewById(R.id.txt_5s);
        txt_5s.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                layBtn.setText("5");
                mLayTime = 5 * 1000;

            }
        });
        txt_10s = (TextView) takeFull.getView().findViewById(R.id.txt_10s);
        txt_10s.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                layBtn.setText("10");
                mLayTime = 10 * 1000;
            }
        });
        //长按连续拍照
        layBtn.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                layBtn.setText(" ");
                takePictureBurst();
                return true;
            }
        });
        //打开led闪光灯
        findViewById(R.id.led).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (lih == 100) {
                    mCaptureRequestBuilder.set(CaptureRequest.FLASH_MODE,
                            CaptureRequest.FLASH_MODE_TORCH);
                    mCaptureRequestBuilder.addTarget(mImageReader.getSurface());
                    try {
                        mCameraCaptureSession.setRepeatingRequest(mCaptureRequestBuilder.build(), null, null);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        //初始化计时器
        mChronometer = takeVideoFrag.getView().findViewById(R.id.chronometer);
        //慢动作
        startSlow = takeVideoFrag.getView().findViewById(R.id.video_start_slow);
        slowText = takeVideoFrag.getView().findViewById(R.id.txt_slow);
        slowText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (stateSlow) {
                    case 1:
                        startSlow.setVisibility(View.VISIBLE);
                        stateSlow = 2;
                        break;
                    case 2:
                        startSlow.setVisibility(View.GONE);
                        stateSlow = 1;
                        break;
                }
            }
        });
        stopSlow = takeVideoFrag.getView().findViewById(R.id.video_stop_slow);
        stopSlow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopRecordingVideo();
                startSlow.setVisibility(View.GONE);
                stopSlow.setVisibility(View.VISIBLE);
            }
        });
        //AWB
        setUpAwb();
        //人脸
        initFace();
        //抓拍

        captureBtn = takeVideoFrag.getView().findViewById(R.id.photoButton2);

        captureBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                capture();
                mImageView2.setVisibility(View.VISIBLE);
            }
        });


    }
    //============获取地理位置=============
    private void getLocation() {
        String serviceStr = Context.LOCATION_SERVICE;// 获取的是位置服务
        LocationManager locationManager = (LocationManager) getSystemService(serviceStr);// 调用getSystemService()方法来获取LocationManager对象
        String provider = LocationManager.NETWORK_PROVIDER;// 指定LocationManager的定位方法
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        Location location = locationManager.getLastKnownLocation(provider);// 调用getLastKnownLocation()方法获取当前的位置信息
        Log.e("TAG", "initPermission: "+location );
        double lat = location.getLatitude();//获取纬度
        double lng = location.getLongitude();//获取经度
        System.out.println(lat+"++++++++++++++++++++");
        // 产生位置改变事件的条件设定为距离改变10米，时间间隔为2秒，设定监听位置变化
        locationManager.requestLocationUpdates(provider, 2000, 10, new LocationListener() {
            @Override
            //这个方法在位置改变时被调用
            public void onLocationChanged(@NonNull Location location) {

            }
        });
        Geocoder geocoder = new Geocoder(this);
        new Thread(){
            @Override
            public void run() {
                try {
                    List<Address> addresses = geocoder.getFromLocation(lat,lng,1);
                    Log.d("info:", "-----get--address--success");
                    if(addresses.size()>0)
                    {
                        msg+="地址："+addresses.get(0).getAddressLine(0);
                    }
                    System.out.println(msg);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
    //============权限申请=============
    private void initPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //动态获取位置权限
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // 检查权限状态
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
                    /**
                     * 用户彻底拒绝授予权限，一般会提示用户进入设置权限界面
                     * 第一次授权失败之后，退出App再次进入时，再此处重新调出允许权限提示框
                     */
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
                    Log.d("info:", "-----get--Permissions--success--1-");

                } else {
                    /**
                     * 用户未彻底拒绝授予权限
                     * 第一次安装时，调出的允许权限提示框，之后再也不提示
                     */
                    Log.d("info:", "-----get--Permissions--success--2-");
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);

                }//
            }

        }

    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) {
            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                    // 申请成功
                    Log.d("info:", "-----get--Permissions--success");
                } else {
                    // 申请失败
                    Toast.makeText(this, "请下次打开时点击允许", Toast.LENGTH_SHORT).show();
                    Log.d("info:", "-----get--Permissions--success");
                }
            }
        }
    }
    //============初始化人脸框=============
    private void initFace() {
        faceView = findViewById(R.id.face_view);
        faceView.setAlpha(0.9f);
    }
    //============设置白平衡=============
    private void setUpAwb() {
        awb_txt = findViewById(R.id.txt_awb);
        awb_txt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stateAwb = 1;
                startPreview();
            }
        });
        awb_img_room = findViewById(R.id.txt_awb_room);
        awb_img_room.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stateAwb = 2;
                startPreview();
            }
        });
        awb_img_sun = findViewById(R.id.txt_awb_sunset);
        awb_img_sun.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stateAwb = 3;
                startPreview();
            }
        });
        awb_img_cloud = findViewById(R.id.txt_awb_cloud);
        awb_img_cloud.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stateAwb = 4;
                startPreview();
            }
        });
        findViewById(R.id.txt_awb_sun).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stateAwb = 5;
                startPreview();
            }
        });
    }
    //============连续拍照=============
    private void takePictureBurst() {
        mMediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.take);
        mMediaPlayer.start();
        try {
            //锁定af
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
            //标准自动曝光，
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
            //闪光灯
            mCaptureRequestBuilder.set(CaptureRequest.FLASH_MODE,CaptureRequest.FLASH_MODE_OFF);
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            mCaptureRequestBuilder.addTarget(mImageReader.getSurface());
            mCaptureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATION.get(rotation));//自动旋转
            //连拍实现，轮询发送请求
            List<CaptureRequest> captureRequests = new ArrayList<>();
            for (int i = 0;i<6;i++){
                Thread.sleep(500);
                captureRequests.add(mCaptureRequestBuilder.build());
            }
            mCameraCaptureSession.captureBurst(captureRequests, new CameraCaptureSession.CaptureCallback() {
                @Override//进行中
                public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
                        unLockFocus();
                }
                @Override//已完成
                public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {

                }
            }, mCameraHandler);
            mCameraCaptureSession.stopRepeating();
            startPreview();
        } catch (CameraAccessException | InterruptedException e) {
            e.printStackTrace();
        }
    }
    //============切换摄像头=============
    private void chooseCamera() {
        //0，表示前置摄像头
        if (mCameraId.equals("0")){
            mCameraId = "1";
            mCameraDevice.close();
            front();
            openCamera();
        }else if (mCameraId.equals("1")) {
            mCameraId = "0";
            mCameraDevice.close();
            openCamera();

        }
    }
    @Override
    protected void onResume() {
        super.onResume();
        //============1=============
        startCameraThread();
        if (!mTextureView.isAvailable()){
            mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
                @Override
                public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
                    //============2设置相机参数=============
                    setupCamera(width,height);
                    //============4开启相机=============
                    openCamera();
                }

                @Override
                public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {

                }

                @Override
                public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
                    return false;
                }

                @Override
                public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {

                }
            });
        }else{
            //startPreview();
        }

    }
    @Override
    protected void onRestart() {
        super.onRestart();
        openCamera();
    }
    ////============1=============
    private void startCameraThread() {
        mCameraThread = new HandlerThread("CameraThread");
        mCameraThread.start();
        mCameraHandler = new Handler(mCameraThread.getLooper());
    }
    //============4打开相机=============
    private void openCamera() {
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
                return;
            }
            manager.openCamera(mCameraId, new CameraDevice.StateCallback() {
                @Override
                public void onOpened(@NonNull CameraDevice camera) {
                    mCameraDevice = camera;
                    //开启预览
                    //============5=============
                    startPreview();
                }

                @Override
                public void onDisconnected(@NonNull CameraDevice camera) {
                    camera.close();
                    mCameraDevice = null;
                }

                @Override
                public void onError(@NonNull CameraDevice camera, int error) {
                    camera.close();
                    mCameraDevice = null;
                }
            }, mCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
    //============2设置相机参数=============
    private void setupCamera(int width, int height) {
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            for (String cameraId : manager.getCameraIdList()){
                CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
                Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
               //默认后置摄像头
                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT)
                continue;
                StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                assert map != null;
                //设置预览大小
                mPreviewSize = getOptimalSize(map.getOutputSizes(SurfaceTexture.class), width, height);
               //获取人脸检测参数
                faceView.setAspectRation(mPreviewSize.getWidth(),mPreviewSize.getHeight());
                int[] FD = characteristics.get(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);
                int maxFD = characteristics.get(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT);
                if(FD.length > 0){
                    List<Integer> fdList = new ArrayList<>();
                    for (int FaceD : FD){
                        fdList.add(FaceD);
                        Log.e("TAG", "setUpCameraOutputs: FD type:" + Integer.toString(FaceD));
                    }
                    Log.e("TAG", "setUpCameraOutputs: FD count" + Integer.toString(maxFD));
                    if (maxFD > 0){
                        mFaceDetectSupported = true;
                        mFaceDetectMode = Collections.max(fdList);
                    }
                }
                //支持的最大检测人脸数量
                maxFaceCount = characteristics.get(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT);
                // 成像区域
                mCameraRect = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
                // 成像尺寸
                mCameraPixelSize = characteristics.get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE);

                mCaptureSize = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), new Comparator<Size>() {
                    @Override
                    public int compare(Size lhs, Size rhs) {
                        return  Long.signum(lhs.getWidth() * lhs.getHeight() - rhs.getHeight() * rhs.getWidth());
                    }
                });
                //============3=============
                setImageReader();
                mCameraId = cameraId;
                break;
            }
        }catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
    //============3设置Image=============
    private void setImageReader() {
        //设置mCaptureSize.getHeight()分辨率为1080P
        mImageReader = ImageReader.newInstance(1920,1080,ImageFormat.JPEG,10);
        mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader reader) {
                //获取下一张，这里连拍必须选这个
                mCameraHandler.post(new imageSaver(reader.acquireNextImage()));
            }
        },mCameraHandler);

    }
    public  class imageSaver implements Runnable{
        private Image mImage;
        private Bitmap bmp;
        public imageSaver(Image image) {
            mImage = image;
        }
        @Override
        public void run( ) {
            ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
            byte[] data = new byte[buffer.remaining()];
            buffer.get(data);
            mImage.close();
            File  mImageFile =new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath());
            if (!mImageFile.exists()){
                mImageFile.mkdir();
            }
            String fileName = msg+System.currentTimeMillis() + ".jpg";
            File file = new File(mImageFile,fileName);
            FileOutputStream fos = null;
            try{
                fos = new FileOutputStream(file);
                //将bitmap保存到流里面
                bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
                bmp.compress(Bitmap.CompressFormat.JPEG,100,fos);
                fos.flush();
                fos.close();
                //imageView获取图片
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        bitmap = BitmapFactory.decodeByteArray(data,0,data.length);
                        mImageView.setImageBitmap(bitmap);
                        mImageView2.setImageBitmap(bitmap);
                        try {
                            Thread.sleep(1000);
                            mImageView2.setVisibility(View.GONE);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (fos != null){
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            //将图片更新到相册
            MediaScannerConnection connection = new MediaScannerConnection(MainActivity.this, null);
            connection.connect();
            connection.scanFile(MainActivity.this,new String[]{file.getAbsolutePath()},new String[]{"image/jpeg"},null);
            }
        }
    //=============获取合适的尺寸==============
    private Size getOptimalSize(Size[] sizeMap, int width, int height) {
        List<Size> sizeList = new ArrayList<>();
        for (Size option:sizeMap
             ) {
            if (width>height){
                if (option.getWidth() > width && option.getHeight() > height){
                    sizeList.add(option);
                }
            }else {
                if (option.getWidth() > height && option.getHeight() > width){
                    sizeList.add(option);
                }
            }
        }
        if (sizeList.size() > 0){
            return Collections.min(sizeList, new Comparator<Size>() {
                @Override
                public int compare(Size lhs, Size rhs) {
                    return Long.signum(lhs.getWidth() * lhs.getHeight() - rhs.getWidth() * rhs.getHeight());
                }
            });
        }
        return sizeMap[0];
    }
    //============5开启预览=============
    private void startPreview() {
        SurfaceTexture mSurfaceTexture = mTextureView.getSurfaceTexture();
        //设置图像缓冲区的默认大小。
        mSurfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(),mPreviewSize.getHeight());
        Surface previewSurface = new Surface(mSurfaceTexture);
        try {
            mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            mCaptureRequestBuilder.addTarget(previewSurface);
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);//标准自动曝光
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);//快速连续对焦
            if (stateAwb == 1){
                mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_AUTO);
                awb_txt.setText("当前白平衡使用于：自动");
            }else if (stateAwb == 2){
                mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_INCANDESCENT);
                awb_txt.setText("当前白平衡使用于：室内");
            }else if (stateAwb == 3){
                mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_TWILIGHT);
                awb_txt.setText("当前白平衡使用于：日落/升");
            }else if (stateAwb == 4){
                mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_CLOUDY_DAYLIGHT);
                awb_txt.setText("当前白平衡使用于：多云");
            }else if (stateAwb == 5){
                mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,CaptureRequest.CONTROL_AWB_MODE_DAYLIGHT);
                awb_txt.setText("当前白平衡使用于：晴天");
            }
            //设置人脸检测
            mCaptureRequestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,mFaceDetectMode);
            //在创建session成功回调返回后开启预览。
            mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()), new CameraCaptureSession.StateCallback() {

                @Override
                public void onConfigured(@NonNull CameraCaptureSession session) {
                    try {
                        mCaptureRequest = mCaptureRequestBuilder.build();
                        mCameraCaptureSession = session;
                        //将生成的预览request发送到camera repeating request queue中。//人脸数量检测
                        mCameraCaptureSession.setRepeatingRequest(mCaptureRequest, new CameraCaptureSession.CaptureCallback() {

                            private void process(CaptureResult result) {
                                /**
                                 * 对摄像头返回的结果进行处理,并获取人脸数据
                                 * @param result 摄像头数据
                                 */
                                Face face[] = result.get(CaptureResult.STATISTICS_FACES);
                                Canvas canvas = faceView.lockCanvas();
                                canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                                if (face.length > -1) {
                                    for (int i = 0; i < face.length; i++) {
                                        Rect mRect = face[i].getBounds();
                                        float scaleWidth = canvas.getHeight() * 1.0f / mCameraPixelSize.getWidth();
                                        float scaleHeight = canvas.getWidth() * 1.0f / mCameraPixelSize.getHeight();
                                        Log.e("TAG", " Scale " + scaleWidth + "," + scaleHeight);
                                        int left = (int) (mRect.left * scaleWidth);
                                        int top = (int) (mRect.top * scaleHeight);
                                        int right = (int) (mRect.right * scaleWidth);
                                        int bottom = (int) (mRect.bottom * scaleHeight);
                                        if (Integer.parseInt(mCameraId) == 1) {
                                            canvas.drawRect(canvas.getWidth() - bottom, canvas.getHeight() - right,
                                                    canvas.getWidth() - top, canvas.getHeight() - left, getPaint());
                                        } else if (Integer.parseInt(mCameraId) == 0) {
                                            canvas.drawRect(canvas.getWidth() - bottom, left, canvas.getWidth() - top, right, getPaint());
                                        }
                                    }
                                }
                                faceText.setText("人脸数量:" + face.length);
                                faceView.unlockCanvasAndPost(canvas);
                            }
                            @Override
                            public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
                                super.onCaptureStarted(session, request, timestamp, frameNumber);
                            }

                            @Override
                            public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
                                process(partialResult);
                            }

                            @Override
                            public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                                process(result);
                            }

                        }, mCameraHandler);
                        /*
                        sendRepeatPreviewRequest 函数通过builder模式给CaptureRequest设置好请求参数，再调用 CameraCaptureSession 的 setRepeatingRequest 方法预览。
                         */

                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession session) {

                }
            },mCameraHandler);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //============人脸框相关=============
    private Paint getPaint() {
        if (mPaint == null) {
            mPaint = new Paint();
            mPaint.setColor(Color.RED);
            mPaint.setStrokeWidth(3f);
            mPaint.setStyle(Paint.Style.STROKE);
        }
        return mPaint;
    }
    //============拍照=============
    public void takePicture(View view) {
        mMediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.take);
        mMediaPlayer.start();

        try {
            //自动对焦
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
            //标准自动曝光，
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
            //关闭闪光灯
            mCaptureRequestBuilder.set(CaptureRequest.FLASH_MODE,CaptureRequest.FLASH_MODE_TORCH);
            mCaptureRequestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,mFaceDetectMode);
            //保存图片
            mCaptureRequestBuilder.addTarget(mImageReader.getSurface());
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            mCaptureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATION.get(rotation));//自动旋转
            mCameraCaptureSession.capture(mCaptureRequestBuilder.build(), new CameraCaptureSession.CaptureCallback() {

                @Override//进行中
                public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
                    unLockFocus();

                }

                @Override//已完成
                public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                    /*try {
                        final CaptureRequest.Builder mCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
                        int rotation = getWindowManager().getDefaultDisplay().getRotation();
                        //保存图片
                        mCaptureBuilder.addTarget(mImageReader.getSurface());
                        mCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATION.get(rotation));//自动旋转
                        mCameraCaptureSession.capture(mCaptureBuilder.build(), new CameraCaptureSession.CaptureCallback() {
                            @Override
                            public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {
                                unLockFocus();
                                //因为拍照和预览用的是同一个captureSession,所以拍照结束后人脸检测失败。
                                startPreview();
                            }
                        }, null);
                        mCameraCaptureSession.stopRepeating();
                        //startPreview();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }*/
                }
            }, mCameraHandler);
            mCameraCaptureSession.stopRepeating();
            startPreview();
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
    //============开启录像=============
    public void startRecordingVideo(View view){
        mMediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.video1);
        mMediaPlayer.start();
        captureBtn.setVisibility(View.VISIBLE);
        try {
            SurfaceTexture texture = mTextureView.getSurfaceTexture();
            assert texture != null;
            texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
            mCaptureVideoBuilder= mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            //设定AF模式
            mCaptureVideoBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO);
            //
           List<Surface> surfaces = new ArrayList<>();
            Surface previewSurface = new Surface(texture);
            surfaces.add(previewSurface);
            if(mMediaRecorder==null)
            {
                setUpMediaRecorder();
            }
            Surface recorderSurface = mMediaRecorder.getSurface();
            surfaces.add(recorderSurface);
            surfaces.add(mImageReader.getSurface());
            mCaptureVideoBuilder.addTarget(recorderSurface);
            mCaptureVideoBuilder.addTarget(previewSurface);

            mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession session) {
                    mCameraVideoSession = session;
                    //计时操作
                    switch (stateTime){
                        case 1 :
                            mChronometer.start();
                            stateTime = 2;
                        case 2:
                            mChronometer.setBase(SystemClock.elapsedRealtime());
                            mChronometer.start();
                            stateTime = 1;
                    }
                    mMediaRecorder.start();
                    //--------无比关键--------
                    updatePreview();
               }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                    Toast.makeText(MainActivity.this, "配置失败！",
                            Toast.LENGTH_SHORT).show();
                }
            },null);

        } catch (Exception e) {
            e.printStackTrace();
        }
        stopBtn.setVisibility(View.VISIBLE);
        startBtn.setVisibility(View.GONE);
    }
    //抓拍
    public void capture(){
        mMediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.take);
        mMediaPlayer.start();
        try {
            mCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            //自动对焦
            mCaptureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
            //标准自动曝光，
            mCaptureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
            //关闭闪光灯
            mCaptureBuilder.set(CaptureRequest.FLASH_MODE,CaptureRequest.FLASH_MODE_OFF);
            mCaptureBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,mFaceDetectMode);
            //保存图片
            mCaptureBuilder.addTarget(mImageReader.getSurface());
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            mCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATION.get(rotation));//自动旋转
            mCameraVideoSession.capture(mCaptureBuilder.build(), new CameraCaptureSession.CaptureCallback() {

                @Override//进行中
                public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) {

                }

                @Override//已完成
                public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {

                }
            }, null);
            mCameraVideoSession.stopRepeating();
            updatePreview();

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }
    //============停止录像=============
    public void stopRecordingVideo(){
        mMediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.video2);
        mMediaPlayer.start();
        mChronometer.stop();
        captureBtn.setVisibility(View.GONE);
        try {
            mMediaRecorder.setOnErrorListener(null);
            mMediaRecorder.stop();
            startPreview();
        } catch (RuntimeException stopException) {

        }
        mMediaRecorder.release();
        mMediaRecorder=null;


    }
    //============开启慢动作录像=============
    public void startRecordingVideoSlow(View view){
        startSlow.setVisibility(View.GONE);
        mMediaPlayer = MediaPlayer.create(MainActivity.this,R.raw.video1);
        mMediaPlayer.start();
        try {
            SurfaceTexture texture = mTextureView.getSurfaceTexture();
            assert texture != null;
            texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
            mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            //设定AF模式
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO);
            //
            List<Surface> surfaces = new ArrayList<>();
            Surface previewSurface = new Surface(texture);
            surfaces.add(previewSurface);
            if(mMediaRecorder==null)
            {
                setUpMediaRecorderSlow();
            }
            Surface recorderSurface = mMediaRecorder.getSurface();
            surfaces.add(recorderSurface);
            mCaptureRequestBuilder.addTarget(recorderSurface);
            mCaptureRequestBuilder.addTarget(previewSurface);//-----------
            mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession session) {
                    mCameraCaptureSession = session;
                    mMediaRecorder.start();
                    //计算操作
                    switch (stateTime){
                        case 1 :
                            mChronometer.start();
                            stateTime = 2;
                        case 2:
                            mChronometer.setBase(SystemClock.elapsedRealtime());
                            mChronometer.start();
                            stateTime = 1;
                    }
                    updatePreview();
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                    Toast.makeText(MainActivity.this, "配置失败！",
                            Toast.LENGTH_SHORT).show();
                }
            },null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        stopBtn.setVisibility(View.VISIBLE);
        startBtn.setVisibility(View.GONE);
    }
    private void setUpMediaRecorder() {
        try {
            mMediaRecorder = new MediaRecorder();
            mMediaRecorder.reset();
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mMediaRecorder.setVideoEncodingBitRate(10000000);//设置视频编码比特率
            mMediaRecorder.setVideoFrameRate(30);//设置视频播放帧速率
            mMediaRecorder.setVideoSize(1280, 720);
            mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//设置视频编码器
            int orientation = 90;
            if (mCameraId.equals("1")){
                orientation = 270;
            }
            mMediaRecorder.setOrientationHint(orientation);
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            //保存到系统相册
            File mVideoFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath());
            if (!mVideoFile.exists()){
                mVideoFile.mkdir();
            }
            String fileName = msg + System.currentTimeMillis() + ".mp4";
            File file = new File(mVideoFile,fileName);

            mMediaRecorder.setOutputFile(file);
            MediaScannerConnection connection = new MediaScannerConnection(MainActivity.this, null);
            connection.connect();
            connection.scanFile(MainActivity.this,new String[]{file.getAbsolutePath()},new String[]{"video/mp4"},null);
            mMediaRecorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void setUpMediaRecorderSlow() {
        try {
            mMediaRecorder = new MediaRecorder();
            mMediaRecorder.reset();
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mMediaRecorder.setVideoEncodingBitRate(10000000);//设置视频编码比特率
            mMediaRecorder.setCaptureRate(120);
            mMediaRecorder.setVideoFrameRate(30);//设置视频播放帧速率
            mMediaRecorder.setVideoSize(1280, 720);
            mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//设置视频编码器
            int orientation = 90;
            if (mCameraId.equals("1")){
                orientation = 270;
            }
            mMediaRecorder.setOrientationHint(orientation);
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            //保存到系统相册
            File mVideoFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath());
            if (!mVideoFile.exists()){
                mVideoFile.mkdir();
            }
            String fileName = msg + System.currentTimeMillis() + ".mp4";
            File file = new File(mVideoFile,fileName);
            mMediaRecorder.setOutputFile(file);
            MediaScannerConnection connection = new MediaScannerConnection(MainActivity.this, null);
            connection.connect();
            connection.scanFile(MainActivity.this,new String[]{file.getAbsolutePath()},new String[]{"video/mp4"},null);
            mMediaRecorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void updatePreview() {
        if (null == mCameraDevice) {
            return;
        }
        try {
            mCaptureVideoBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
            mCameraVideoSession.setRepeatingRequest(mCaptureVideoBuilder.build(), null, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
    private void unLockFocus() {
        try {
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
            mCameraCaptureSession.setRepeatingRequest(mCaptureRequest,null,mCameraHandler);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}